package com.example.myapplication.algorithm;

import java.util.LinkedList;
import java.util.Queue;

public class MovingAverageSmoother {
    private static MovingAverageSmoother INSTANCE;
    public synchronized static MovingAverageSmoother getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new MovingAverageSmoother(50);
        }
        return INSTANCE;
    }
    private static MovingAverageSmoother INSTANCE1;
    public synchronized static MovingAverageSmoother getInstance1() {
        if (INSTANCE1 == null) {
            INSTANCE1 = new MovingAverageSmoother(50);
        }
        return INSTANCE1;
    }
    private static MovingAverageSmoother INSTANCE2;
    public synchronized static MovingAverageSmoother getInstance2() {
        if (INSTANCE2 == null) {
            INSTANCE2 = new MovingAverageSmoother(5);
        }
        return INSTANCE2;
    }
    private final int windowSize;  // 滑动窗口大小
    private final Queue<Double> window; // 窗口队列
    private double sum;           // 窗口内数据的和
    public MovingAverageSmoother(int windowSize) {
        if (windowSize <= 0) {
            throw new IllegalArgumentException("Window size must be positive.");
        }
        this.windowSize = windowSize;
        this.window = new LinkedList<>();
        this.sum = 0.0;
    }

    /**
     * 实时添加新数据并返回平滑后的值
     * @param newValue 新数据点
     * @return 平滑后的值
     */
    public double smooth(double newValue) {
        // 如果窗口已满，移除最旧的数据
        if (window.size() == windowSize) {
            sum -= window.poll();
        }
        // 添加新数据并更新和
        window.add(newValue);
        sum += newValue;
        // 返回平均值
        return sum / window.size();
    }

    /**
     * 批量平滑处理（非实时，适用于已有完整数据）
     * @param data 原始数据数组
     * @param windowSize 窗口大小
     * @return 平滑后的数据数组
     */
    public static double[] smoothArray(double[] data, int windowSize) {
        MovingAverageSmoother smoother = new MovingAverageSmoother(windowSize);
        double[] smoothedData = new double[data.length];
        for (int i = 0; i < data.length; i++) {
            smoothedData[i] = smoother.smooth(data[i]);
        }
        return smoothedData;
    }
}
